package com.syq.dao.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.syq.dao.RedisDao;
import com.syq.dao.RedisGeneratorDao;
import com.syq.dto.DTO;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

@Component("redisDao")
public class RedisDaoImp  extends RedisGeneratorDao implements RedisDao {
    /**
     * 删除对象 ,依赖key
     */
    public void delete(String key) {
        List<String> list = new ArrayList<String>();
        list.add(key);
        delete(list);
    }
    public <T> T get(String keyId,Class<T> clazz){
        T result = redisTemplate.execute(new RedisCallback<T>() {
            public T doInRedis(RedisConnection connection)
                    throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] key = serializer.serialize(keyId);
                byte[] value = connection.get(key);
                GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();

                System.out.println(value);
                if (value == null) {
                    return null;
                }

//                Object json = jackson2JsonRedisSerializer.deserialize(value,clazz);
                System.out.println("------333333------");
               // T t = jackson2JsonRedisSerializer.deserialize(json.toString().getBytes(StandardCharsets.UTF_8),clazz);//将字符串反序列化成对象
                T t = null;
                try {
                    t = new ObjectMapper().readValue(value,clazz);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                // System.out.println(json);
                return t;
            }
        });
        return result;
    }
    public  <T> void save(String key,T t ,Long time) {
        Optional<Long> timeOp = Optional.ofNullable(time);
        Long expirTime=  timeOp.isPresent()?timeOp.get():120L;
        GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        redisTemplate.opsForValue().set(key,jackson2JsonRedisSerializer.serialize(t),expirTime, TimeUnit.SECONDS);
    }

    public  <T> void saveJson(String key,T t ,Long time) throws JsonProcessingException {
        Optional<Long> timeOp = Optional.ofNullable(time);
        Long expirTime=  timeOp.isPresent()?timeOp.get():120L;

        redisTemplate.opsForValue().set(key,new ObjectMapper().writeValueAsString(t),expirTime, TimeUnit.SECONDS);
    }
    /**
     * 删除集合 ,依赖key集合
     */
    public void delete(List keys) {
        redisTemplate.delete(keys);
    }

    public String get(String keyId){
        String result = redisTemplate.execute(new RedisCallback<String>() {
            public String doInRedis(RedisConnection connection)
                    throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] key = serializer.serialize(keyId);
                byte[] value = connection.get(key);
                System.out.println(value);
                if (value == null) {
                    return null;
                }
                String json = serializer.deserialize(value);//将字符串反序列化成对象
               // System.out.println(json);
                return json;
            }
        });
        return result;
    }
    @Override
    public <T> DTO<T> getByJSon(String keyId, Class<T> clazz) {
        DTO<T> dto = redisTemplate.execute(new RedisCallback<DTO<T>>() {
            public  DTO<T> doInRedis(RedisConnection connection)
                    throws DataAccessException {
                GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] key = serializer.serialize(keyId);
                byte[] value = connection.get(key);
                //默认的序列化器反序列化
               return null;
                // return     JacksonUtils.deserialize(jackson2JsonRedisSerializer.deserialize(value),);
            }
        },true,false);
        return dto;
    }

    /**
     * 根据key模糊查询
     * @param stringRedisTemplate
     * @param match
     * @param count
     * @return
     */
    private static Cursor<String> scan(StringRedisTemplate stringRedisTemplate, String match, int count){
        ScanOptions scanOptions = ScanOptions.scanOptions().match(match).count(count).build();
        RedisSerializer<String> redisSerializer = (RedisSerializer<String>) stringRedisTemplate.getKeySerializer();
        return (Cursor) stringRedisTemplate.executeWithStickyConnection((RedisCallback) redisConnection ->
                new ConvertingCursor<>(redisConnection.scan(scanOptions), redisSerializer::deserialize));
    }
    public <T>  List<String> getValuesListByKeyRegexp(StringRedisTemplate stringRedisTemplate,String pattern) throws IOException {
        List<String> keys = new ArrayList<>();
        Cursor<String> cursor = scan(stringRedisTemplate, pattern, 200);
        while (cursor.hasNext()) {
            //找到一次就添加一次
            keys.add(cursor.next());
        }
        cursor.close();
        keys.forEach(System.out::println);
        return  keys;
    }

}
